package org.yunai.swjg.server.module.battle.operation;

import org.yunai.swjg.server.core.service.Online;
import org.yunai.swjg.server.module.battle.BattleDef;
import org.yunai.swjg.server.module.battle.BattleUtils;
import org.yunai.swjg.server.module.battle.unit.BattleTeam;
import org.yunai.swjg.server.module.battle.unit.BattleUnit;
import org.yunai.swjg.server.core.role.AbstractRole;
import org.yunai.swjg.server.module.battle.vo.BattleAction;
import org.yunai.yfserver.async.IIoOperation;
import org.yunai.yfserver.util.MathUtils;

import java.util.Iterator;

/**
 * 基础战斗操作
 * User: yunai
 * Date: 13-5-17
 * Time: 下午9:41
 */
public abstract class BaseBattleOperation implements IIoOperation {

    /**
     * 进攻队伍
     */
    protected BattleTeam attackTeam;
    /**
     * 防守队伍
     */
    protected BattleTeam defenseTeam;

    public BattleTeam getAttackTeam() {
        return attackTeam;
    }

    public BattleTeam getDefenseTeam() {
        return defenseTeam;
    }

    // ==================== 业务方法 ====================

    public BaseBattleOperation(Online online, boolean attackIsFullHp) {
        attackTeam = new BattleTeam(BattleDef.Team.ATTACK);
        // TODO 精简版（不带宠物）
        AbstractRole role = online.getPlayer();
        addBattleUnit(role, attackTeam, 1, attackIsFullHp);
    }

    protected void addBattleUnit(AbstractRole role, BattleTeam team, int unitIndex, boolean isFullHp) {
        // 构建战斗单元
        BattleUnit unit = BattleUnit.gen(role, team,  unitIndex, isFullHp);
        // 加入队伍
        team.addUnit(unit);
    }

    private void battle() {
        int currentRound = 1; // 当前回合
        while (currentRound < BattleUtils.ROUND_MAX && attackTeam.isAlive() && defenseTeam.isAlive()) {
            BattleAction roundAction = new BattleAction(currentRound);

            // TODO 先不考虑谁先攻击
            Iterator<BattleUnit> attackIterator = attackTeam.getAlives().values().iterator();
            Iterator<BattleUnit> defenseIterator = defenseTeam.getAlives().values().iterator();
            while (attackIterator.hasNext() || defenseIterator.hasNext()) {
                // 进攻方
                if (!defenseTeam.checkAlive()) {
                    break;
                }
                BattleUnit attackUnit = findBattleUnit(attackIterator);
                if (attackUnit != null) {
                    attackUnit.doAction(this, roundAction);
                }
                // 防守方
                if (!attackTeam.checkAlive()) {
                    break;
                }
                BattleUnit defenseUnit = findBattleUnit(defenseIterator);
                if (defenseUnit != null) {
                    defenseUnit.doAction(this, roundAction);
                }
            }

            // 移除死亡的战斗单元
            clearDeathBattleUnit(attackTeam);
            clearDeathBattleUnit(defenseTeam);
        }


        // TODO 战斗（隐藏模式 哟哟）
        boolean attWin = MathUtils.nextBoolean();
//        defenseTeam.getUnits().get(0).setHpCur(defenseTeam.getUnits().get(0) .getHpCur()
//                - attackTeam.getUnits().get(0).getHpCur());
//        if (defenseTeam.getUnits().get(0).getHpCur() < 0) {
//            defenseTeam.getUnits().get(0).setHpCur(0);
//        }
        endImpl(attWin);
    }

    private BattleUnit findBattleUnit(Iterator<BattleUnit> unitIterator) {
        if (!unitIterator.hasNext()) {
            return null;
        }
        do {
            BattleUnit unit = unitIterator.next();
            if (unit.isAlive()) {
                return unit;
            }
        } while (unitIterator.hasNext());
        return null;
    }

    private void clearDeathBattleUnit(BattleTeam team) {
        Iterator<BattleUnit> unitIterator = team.getAlives().values().iterator();
        while (unitIterator.hasNext()) {
            if (!unitIterator.next().isAlive()) {
                unitIterator.remove();
            }
        }
    }

    @Override
    public State doStart() {
        return State.STARTED;
    }

    @Override
    public State doIo() {
        try {
            battle();
        } catch (Exception e) {
            // TODO log
            e.printStackTrace();
        }
        return State.IO_DONE;
    }

    /**
     * 战斗结束子类拓展实现
     *
     * @param attWin 攻击方是否胜利
     */
    protected abstract void endImpl(boolean attWin);

    @Override
    public State doFinish() {
        return State.FINISHED;
    }
}
